#pragma once

#define MAX_LOGBUFFER_SIZE 2048

class InputKeyEvent;
class Logger
{
public:
						Logger();
	virtual				~Logger();

	virtual void		Write(const char* format, va_list arg) = 0;
	virtual void		InputUpdate(InputKeyEvent* evt)	{}

	bool				IsActivate()					{ return m_Active; }
	void				SetActivate(bool isActive)		{ m_Active = isActive; }
	
	bool				IsInputUpdate()					{ return m_InputUpdated;}

protected:
	bool				m_Active;
	bool				m_InputUpdated;
};

//////////////////////////////////////////////////////////////////////////

class OSLogger : public Logger
{
public:
						OSLogger();

	virtual void		Write(const char* format, va_list arg);
};

//////////////////////////////////////////////////////////////////////////

class FrameUpdatedEvent;
class ConsoleLogger : public Logger
{
public:
									ConsoleLogger();
	virtual							~ConsoleLogger();

	virtual void					Write(const char* format, va_list arg);
	virtual void					InputUpdate(InputKeyEvent* evt);
	void							ConsoleUpdate(FrameUpdatedEvent* evt);

public:
	void							Init();
	void							Shutdown();

	bool							IsVisible();
	void							SetVisible(bool visible);

private:
	typedef TTightQueue<String>		StringQueue;
	typedef std::list<String>		StringList;
	typedef TTightQueue<StringList>	StringListQueue;
	typedef std::map<uint, char>	KeyMap;

private:
	void							ChangedInputConsole();
	bool							UpdateDelayKeyTime();
	void							ClearDelayKeyTime();
	void							createLine(StringList::iterator nextiter);	

#ifdef _WIN32
	void							CopyToClipboard();
#endif

private:
	Root*							m_root;
	SceneManager*					m_logSceneManager;
	SceneNode*						m_logNode;
	
	Rectangle2D*					m_printArea;
	Rectangle2D*					m_inputArea;
	
	Overlay*						m_overlay;

	OverlayElement*					m_printText;
	OverlayElement*					m_inputText;

	bool							m_Visibled;
	bool							m_KeyUpdated;
	float							m_BackDeleteDelay;
	float							m_beforeBackDelete;

private:
	float							m_printButtom;
	float							m_inputTop;
	const float						m_onelineHeight;
	const int						m_pagelinecount;
	int								m_currEndline;
	int								m_extendInputline;

	bool							m_CursorBlinkOn;
	float							m_CursorTime;

private:
	KeyMap							m_ShiftKeymap;
	KeyMap							m_Keymap;

	int								m_curInputidx;
	int								m_cursorPos;

	StringQueue						m_loglist;
	StringList						m_inputlist;
	StringList::iterator			m_curInputiter;

	StringListQueue					m_inputHistory;
	uint							m_historyidx;
};